<template>
  <div class="route-detail">
    <div class="header">
      <div class="bg">
        <img :src="routeDetail.cover" alt="" />
      </div>
      <div class="user-info">
        <div class="left">
          <div
            class="avatar"
            @click="otherUserInfo(routeDetail)"
            :style="{
              'pointer-events': routeDetail.createUser === -1 ? 'none' : 'auto',
            }"
          >
            <img :src="routeDetail.avatar || defaultAvatar" alt="" />
          </div>
          <div class="info">
            <div class="title">
              {{ routeDetail.name }}
            </div>
            <div class="user">
              <span
                class="nickname"
                :style="{
                  'pointer-events':
                    routeDetail.createUser === -1 ? 'none' : 'auto',
                }"
                @click="otherUserInfo(routeDetail)"
                >{{ routeDetail.nickName }}</span
              >
              <span class="publish-time">
                <i class="el-icon-date"></i>
                {{ formatDate(routeDetail.createTime) }}
              </span>
              <span class="views"
                ><i class="el-icon-view"></i>{{ routeDetail.views }}</span
              >
            </div>
          </div>
        </div>
        <div class="right">
          <svg
            width="36"
            height="36"
            viewBox="0 0 48 48"
            fill="rgb(250, 40, 40)"
            class="icon"
            xmlns="http://www.w3.org/2000/svg"
            @click="update"
          >
            <path
              d="M15 8C8.92487 8 4 12.9249 4 19C4 30 17 40 24 42.3262C31 40 44 30 44 19C44 12.9249 39.0751 8 33 8C29.2797 8 25.9907 9.8469 24 12.6738C22.0093 9.8469 18.7203 8 15 8Z"
              :fill="praise === 0 ? 'none' : '#F56C6C'"
              stroke="#F56C6C"
              stroke-width="4"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
          <span>{{ routeDetail.praise }}点赞</span>
        </div>
      </div>
    </div>
    <div class="body" ref="targetElement">
      <div class="content" v-html="formattedText"></div>
      <div class="option" v-show="!isShow">
        <div class="look-remark" @click="lookRemark">
          <i class="el-icon-view"></i>
          <span>查看评论</span>
        </div>
        <div class="write-remark" @click="dialogVisible = true">
          <i class="el-icon-s-promotion"></i>
          <span>写评论</span>
        </div>
        <div class="write-remark" @click="goTop" v-show="scrollTop > 700">
          <i class="el-icon-upload2"></i>
          <span>回顶部</span>
        </div>
      </div>
    </div>
    <!-- 评论 -->
    <div class="remark user-common-bg">
      <div class="remark-left">
        <RemarkView
          :remarkListLoading="remarkListLoading"
          :remarkList="dataList"
          :total="total"
          @getRemarkList="getRemarkList"
        ></RemarkView>
        <!-- 分页 -->
        <el-pagination
          v-show="dataList.length > 0"
          background
          layout="prev, pager, next"
          :total="total"
          :current-page="currentPage"
          :page-size="pageSize"
          @current-change="handleCurrentChange"
          :page-count="7"
          style="text-align: right; margin-top: 24px"
        >
        </el-pagination>
      </div>
      <div class="remark-right" v-show="isShow">
        <div class="write-remark" @click="dialogVisible = true">
          <i class="el-icon-s-promotion"></i>
          <span>写评论</span>
        </div>
        <div class="write-remark" @click="goTop" v-show="scrollTop > 700">
          <i class="el-icon-upload2"></i>
          <span>回顶部</span>
        </div>
      </div>
    </div>
    <!-- 写评论 -->
    <el-dialog
      title="写评论"
      :visible.sync="dialogVisible"
      width="56%"
      @close="handleClose"
      :close-on-click-modal="false"
    >
      <div class="editor-container">
        <Toolbar
          style="border-bottom: 1px solid #ccc"
          :editor="editor"
          :defaultConfig="toolbarConfig"
          :mode="mode"
        />
        <Editor
          style="height: 210px; overflow-y: hidden"
          v-model="html"
          :defaultConfig="editorConfig"
          :mode="mode"
          @onCreated="onCreated"
        />
      </div>
      <span slot="footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addRemark" :loading="insertLoading"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import RemarkView from "@/components/RemarkView.vue";
import defaultAvatar from "@/assets/defaultAvatar.png";
import { getRouteById, isPraise, updatePraise } from "@/api/user/route";
import userModule from "@/utils/userInfo";
import { Notification } from "element-ui";
import { addRemark, getRemarkList } from "@/api/user/remark";
import { addVisitor } from "@/api/user/user";

export default {
  name: "RouteDetail",
  props: ["id"],
  components: {
    RemarkView,
    Editor,
    Toolbar,
  },
  data() {
    return {
      defaultAvatar,
      routeDetail: {
        detail: "",
      },
      praise: 0,
      scrollTop: 0,
      isShow: false,
      dataList: [],
      page: 1,
      pageSize: 10,
      total: 0,
      currentPage: 1,
      dialogVisible: false,
      insertLoading: false,
      remarkListLoading: false,
      // 富文本框配置
      editor: null,
      html: "",
      toolbarConfig: {
        // 排除菜单中的上传图片和上传视频功能
        excludeKeys: ["group-image", "insertVideo"],
      },
      editorConfig: {
        placeholder: "请输入内容...",
        MENU_CONF: {},
      },
      mode: "simple", // or 'simple'
    };
  },
  computed: {
    formattedText() {
      return this.routeDetail.detail
        .replace(/<p>/g, '<p style="line-height:30px">')
        .replace(/<img([^>]*)>/g, '<img$1 style="width:100%">');
    },
  },
  created() {
    this.getRouteById();
    this.isPraise();
    this.getRemarkList();
  },
  mounted() {
    window.addEventListener("scroll", this.handleScroll);
    this.handleScroll(); // 组件挂载时立即执行一次，确保初始位置正确
  },
  beforeDestroy() {
    window.removeEventListener("scroll", this.handleScroll);

    const editor = this.editor;
    if (editor == null) return;
    editor.destroy(); // 组件销毁时，及时销毁编辑器
  },
  methods: {
    // 获取路线详情
    async getRouteById() {
      const res = await getRouteById({ id: this.id });
      this.routeDetail = res.data;
    },
    // 添加评论
    async addRemark() {
      const content = this.html;
      if (content === "") {
        this.$message.warning("请输入评论内容");
        return;
      }
      try {
        this.insertLoading = true;
        const res = await addRemark({
          userId: userModule.getUser().id,
          type: "route",
          typeId: this.id,
          content,
        });
        this.dialogVisible = false;
        this.getRemarkList();
      } finally {
        this.insertLoading = false;
      }
    },
    // 获取评论列表
    async getRemarkList() {
      try {
        this.remarkListLoading = true;
        const res = await getRemarkList({
          page: this.page,
          pageSize: this.pageSize,
          type: "route",
          typeId: this.id,
        });
        this.dataList = res.data.records;
        this.total = res.data.total;
      } catch {
        this.$message.error("获取评论列表失败");
      } finally {
        this.remarkListLoading = false;
      }
    },
    // 是否点赞
    async isPraise() {
      const res = await isPraise({
        userId: userModule.getUser().id,
        routeId: this.id,
      });
      this.praise = res.data.idPraise;
    },
    // 点赞
    async update() {
      const notify = Notification({
        title: "请稍后...",
        showClose: false,
        iconClass: "el-icon-loading",
        duration: 0,
      });
      try {
        const res = await updatePraise({
          userId: userModule.getUser().id,
          routeId: this.id,
          isPraise: this.praise === 0 ? 1 : 0,
        });
        this.getRouteById();
        this.isPraise();
        notify.close();
        Notification.success({
          title: "操作成功",
          duration: 2000,
        });
      } catch {
        notify.close();
        Notification.error({
          title: "错误",
          message: "操作失败",
          duration: 2000,
        });
      }
    },
    // 查看评论
    lookRemark() {
      // 获取整个页面高度
      // document.body.scrollHeight
      // 获取指定容器的高度
      const height = this.$refs.targetElement.offsetHeight;
      window.scrollTo({
        top: height + 400,
        behavior: "smooth",
      });
    },
    // 查看用户信息
    async otherUserInfo(item) {
      const currentUserId = userModule.getUser().id;
      if (item.createUser === currentUserId) {
        this.$router.push("/private");
      } else {
        // 增加访问量
        const res = await addVisitor({ id: item.createUser });
        this.$router.push({ name: "other", params: { id: item.createUser } });
      }
    },
    // 回顶部
    goTop() {
      window.scrollTo({
        top: 0,
        behavior: "smooth",
      });
    },
    // 时间格式判断
    padZero(num) {
      return num < 10 ? "0" + num : num;
    },
    // 时间格式化
    formatDate(timeArray) {
      if (!timeArray) return "暂无时间";
      let year = timeArray[0];
      let month = this.padZero(timeArray[1]);
      let day = this.padZero(timeArray[2]);
      let hour = this.padZero(timeArray[3]);
      let minute = this.padZero(timeArray[4]);
      let second = this.padZero(timeArray[5]) || "00";
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
    },
    // 分页
    handleCurrentChange(page) {
      this.page = page;
      this.currentPage = page;
      this.getRemarkList();
    },
    // 获取滚动条高度
    handleScroll() {
      this.scrollTop = window.scrollY;
      // 获取指定容器的高度
      const height = this.$refs.targetElement.offsetHeight;
      this.isShow = this.scrollTop > height + 400;
    },
    // 富文本框配置
    onCreated(editor) {
      this.editor = Object.seal(editor); // 一定要用 Object.seal() ，否则会报错
    },
    // 关闭对话框
    handleClose() {
      this.html = "";
    },
  },
};
</script>

<style lang="less" scoped>
.route-detail {
  .header {
    width: 100%;
    min-height: 300px;
    box-shadow: 0 2px 6px #cfcfcf;
    .bg {
      width: 100%;
      height: 450px;
      img {
        width: 100%;
        height: 100%;
      }
    }
    .user-info {
      display: flex;
      margin: 0 auto;
      width: 76%;
      height: 80px;
      .left {
        position: relative;
        width: 90%;
        .avatar {
          position: absolute;
          top: -60px;
          width: 100px;
          height: 100px;
          border-radius: 50%;
          cursor: pointer;
          img {
            width: 100%;
            height: 100%;
            border-radius: inherit;
          }
        }
        .info {
          position: absolute;
          top: -50px;
          left: 120px;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
          width: 80%;
          height: 110%;
          text-align: left;
          .title {
            font-size: 20px;
            font-weight: 600;
            color: #fff;
          }
          .user {
            font-size: 14px;
            .nickname {
              color: #ff7200;
              margin-right: 8px;
              cursor: pointer;
            }
            .publish-time {
              color: #999;
              margin-right: 8px;
              i {
                margin-right: 4px;
              }
            }
            .views {
              color: #999;
              i {
                margin-right: 4px;
              }
            }
          }
        }
      }
      .right {
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        border-left: 1px solid #cfcfcf;
        border-right: 1px solid #cfcfcf;
        .icon {
          cursor: pointer;
        }
        span {
          display: block;
          margin-top: 4px;
          font-size: 13px;
        }
      }
    }
  }
  .body {
    display: flex;
    margin: 20px auto;
    width: 76%;
    .content {
      width: 80%;
      text-align: left;
      padding-right: 10px;
      border-right: 1px solid #ddd;
    }
    .option {
      position: sticky;
      top: 100px;
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 0 10px;
      min-width: 140px;
      height: 90px;
      margin-left: 10px;
      border-radius: 6px;
      box-shadow: 0 0 6px #cfcfcf;
      .look-remark,
      .write-remark {
        display: flex;
        flex-direction: column;
        justify-content: center;
        width: 60px;
        height: 60px;
        cursor: pointer;
        &:nth-of-type(2),
        &:nth-of-type(3) {
          border-left: 1px solid #ddd;
        }
        &:hover {
          i {
            transform: scale(1.1);
            color: rgb(102, 177, 255);
          }
          span {
            color: rgb(102, 177, 255);
          }
        }
        i {
          font-size: 28px;
          transition: all 0.3s;
        }
        span {
          font-size: 12px;
        }
      }
    }
  }
  .remark {
    display: flex;
    margin: 10px auto;
    min-height: 300px;
    border-top: 1px dashed #eee;
    .remark-left {
      width: 94%;
    }
    .remark-right {
      position: fixed;
      right: 80px;
      bottom: 50%;
      flex: 1;
      margin-top: 60px;
      margin-left: 4px;
      .write-remark {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        background-color: #fff;
        margin-bottom: 10px;
        width: 70px;
        height: 70px;
        cursor: pointer;
        border-radius: 6px;
        box-shadow: 0 2px 4px #cfcfcf;
        &:nth-of-type(2) {
          border-top: 1px solid #ddd;
        }
        &:hover {
          i {
            transform: scale(1.1);
            color: rgb(102, 177, 255);
          }
          span {
            color: rgb(102, 177, 255);
          }
        }
        i {
          font-size: 28px;
          transition: all 0.3s;
        }
        span {
          font-size: 12px;
        }
      }
    }
  }
  .editor-container {
    text-align: left;
    height: 300px;
    border: 1px solid;
  }
}
</style>